# coding=utf-8
"""
    Flask 启动
"""

import os
import importlib
from flask import Flask, request, g, current_app
from config import conf
from routes import register_blueprints
from utils.conf_util import conf_handler
from utils.log_util import LoggerUtil
from utils.token_util import token_required
from base.base_res import res_not_found, base_response, res_base


# @Time    :  2024-10-16 17:27:29
# @Author  :  jiangtong
# @Email   :  gingerqgyy@outlook.com
# @Project :  ginger_yl_test_boost
# @File    :  app.py


def create_app(conf_name, _is_verify_token=True):
    """
    初始化 Flask App
    :param conf_name: 配置获取, { dev / test / prod }, default == dev
    :param _is_verify_token: 是否校验 token, 默认 True, 表示校验 token
    """

    # 创建 app :
    _app = Flask(__name__)
    _app.config.from_object(conf[conf_name])

    # 注册日志 : ( 需要先注册日志, 因为初始化数据库时会用到日志记录 )
    logger = LoggerUtil(_app)
    logger.info(f'Starting app in {conf_name} mode')

    # 初始化 app 信息 : ( 密钥, 日志, 数据库 )
    conf[conf_name]().init_app(_app)

    # 注册错误处理器 :
    _app.register_error_handler(404, res_not_found)

    # 注册全局拦截器 : ( 请求处理前处理 )
    @_app.before_request
    def before_request():
        g.new_token, g.token_status = None, None
        current_app.logger.info(f'Request Method: {request.method}, Request Path: {request.path}')
        # 打印请求数据
        if request.method == 'GET':
            current_app.logger.info(f'Query Parameters: {request.args}')
        elif request.method == 'POST':
            current_app.logger.info(f'JSON Data: {request.get_json()}')
        # 忽略特定的路径 :
        if _is_verify_token and request.endpoint != 'user.login' and request.endpoint != 'user.refresh_token':
            is_validation, new_token, error_res = token_required()
            """
            1. X -> 跳登录
            2. Y -> 直接更新 access_token,
            3. Z -> 通过 refresh_token 更新 access_token
            """
            if not is_validation:
                g.token_status = 'X'
                return base_response(*error_res)
            if new_token:
                g.token_status = 'Y'
                g.new_token = new_token
            if new_token is None and error_res:
                g.token_status = 'Z'

    # 注册全局拦截器 : ( 请求处理后处理 )
    @_app.after_request
    def after_request(response):
        # 检查 before_request 中是否标记了 token 状态
        if hasattr(g, 'token_status'):
            response.headers['Token-Invalid'] = g.token_status
            if g.token_status == 'X':
                # Token 失效, 跳转登录 :
                pass
            elif g.token_status == 'Y':
                # Token 需要刷新
                response.json['access_token'] = g.new_token
            elif g.token_status == 'Z':
                # access_token 需要通过 refresh_token 刷新 :
                response.headers['Token-Invalid'] = 'Z'
        return response

    # 注册蓝图 ( 路由模块 ) :
    # _app.register_blueprint(user_bp, url_prefix='/users')
    register_blueprints(_app)

    return _app


if __name__ == '__main__':
    pass

    # 提取配置 :
    is_verify_token = conf_handler.get('venv', 'is_verify_token')
    venv = conf_handler.get('venv', 'venv')

    app = create_app(conf_name=venv, _is_verify_token=is_verify_token)
    app.run(host='0.0.0.0', port=80, debug=True)

    # 启动命令 :
    # poetry run python app.py
